#include<iostream>
#include<cuda_runtime.h>
#include<vector>
#include "../MyTimer.h"
#include<string>
#include<math.h>
#include<sstream>


bool is_same(double* a, double *b, int len)
{
    for(int i = 0; i < len; i++)
    {
        if(i < 100)
        {
            std::cout << a[i] <<" " << b[i] << std::endl;
        }
        if(a[i] != b[i])
            return 0;
    }
    return 1;
}
double* copy(double* in, int len)
{
    double* d = new double[len];
    for(int i = 0; i < len; i++)
    {
        d[i] = in[i];
    }
    return d;
}
double* init(int len)
{
    double* d = new double[len];
    for(int i = 0; i < len; i++)
    {
        d[i] = pow((double(rand()%100+1) / 100), 2);
    }
    return d;
}
__device__ double myAtomicAdd(double* ptr, double val)
{

}
__global__ void cal(double* in1, double* in2, int len)
{
    int index = blockDim.x * blockIdx.x + threadIdx.x;
    if(index < len)
        in1[index] = in1[index] + in2[index];
}

__global__ void cal_atomic(double* in1, double* in2, int len)
{
    int index = blockDim.x * blockIdx.x + threadIdx.x;
    double return_val = 0;
    if(index < len)
        return_val = myAtomicAdd(&in1[index], in2[index]);
}

int main()
{
    int len = 1 << 20;
    int block_size = 1<<10;
    int grid_size = (len + block_size - 1) / block_size;

    double* origin = init(len);
    double* in2 = init(len);
    double* in1_1 = copy(origin);
    double* in1_2 = copy(origin);

    GPUTimer t;
    t.start();
    cal<<<grid_size, block_size>>>(in1_1, in2, len);
    float ms1 = t.stop();


    
    t.start();
    cal_atomic<<<grid_size, block_size>>>(in1_2, in2, len);
    float ms2 = t.stop();


    std::cout << is_same(in1_1, in1_2, len)<<" common" << ms1 <<" atomic" << ms2;

}




































